#include <signal.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include "log.h"
#include "UMManage.h"
#include "fake.h"
#include <string.h>

void process_notify_normal(int pid)
{
    // TODO 5 is a magic number
    if (get_num_of_ocall_and_eret() < 1e9)
    {
        // TEST_PRINT("notify_normal\n");
        kill(pid, SIGUSR1);
    }
    // 这段代码是无意义的，由于创建了子进程，因此在父/子进程中，子/父进程的内存空间是无法访问的
    // else if (!has_ret)
    // {
    //     TEST_ASSERT_INFO(false, "has_ret == false , MUST notify_normal");
    // }
}

void process_notify_enclave(int pid)
{
    if (get_num_of_ecall_and_oret() < 1e9)
    {
        // TEST_PRINT("notify_enclave\n");
        kill(pid, SIGUSR1);
    }
    // 这段代码是无意义的，由于创建了子进程，因此在父/子进程中，子/父进程的内存空间是无法访问的
    // else if (!has_call)
    // {
    //     TEST_ASSERT_INFO(false, "has_call == false , MUST notify_enclave");
    // }
}

static void process_fake_enclave(void *shared_buffer, int pid)
{
    signal(SIGUSR1, fake_enclave_signal_handler);
    fake_enclave(shared_buffer, process_notify_normal, pid);
}

static void process_fake_normal(void *shared_buffer, int pid)
{
    signal(SIGUSR1, fake_normal_signal_handler);
    fake_normal(shared_buffer, process_notify_enclave, pid);
}

int test_uintr_process()
{
    int shmId;
    void *shmPtr;

    // 创建共享内存段
    shmId = shmget(IPC_PRIVATE, UM_SIZE, IPC_CREAT | 0666);
    if (shmId == -1)
    {
        LOG("Failed to create shared memory!");
        return 1;
    }

    // 将共享内存连接到当前进程的地址空间
    shmPtr = shmat(shmId, NULL, 0);
    if (shmPtr == (void *)-1)
    {
        LOG("Failed to attach shared memory!");
        return 1;
    }

    memset(shmPtr, 0, UM_SIZE);

    pid_t pid = fork(); // 创建子进程

    if (pid == -1)
    {
        // 创建子进程失败
        LOG("Failed to create child process!");
        return 1;
    }
    else if (pid == 0)
    {
        void *shared_memory_ptr_child = shmat(shmId, (void *)0x20000000, 0);
        if (shared_memory_ptr_child == (void *)-1ULL)
        {
            LOG("Failed to attach shared memory in child process");
            return 1;
        }

        // 子进程代码
        LOG("This is the child process, shared_memory=%p\n", shared_memory_ptr_child);

        process_fake_enclave(shared_memory_ptr_child, getppid());

        if (shmdt(shared_memory_ptr_child) == -1) // 分离共享内存
        {
            LOG("shmdt error\n");
        }
        LOG("Child process exit\n");
    }
    else
    {
        // 父进程代码
        LOG("This is the parent process, shared_memory=%p\n", shmPtr);

        process_fake_normal(shmPtr, pid);

        waitpid(pid, NULL, 0); // 等待子进程运行结束
        shmdt(shmPtr);         // 分离共享内存
        // 删除共享内存段
        shmctl(shmId, IPC_RMID, NULL);
    }

    LOG("SUCCESS!\n");
    return 0;
}
